#ifndef __main__
#define __main__
#include <iostream>
#include <string>
#include <list>
#include <map>
#include <cassert>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>

#include "error.h"
#include "object.h"
#include "symbol.h"
#include "port.h"
#include "environment.h"
#include "number.h"
#include "string.h"
#include "cons.h"
#include "funcs.h"
#include "reader.h"

class tizp {
    Environment env;

public:
    tizp(): env(new environment()) { }
    void set_port(std::string name) {
	Symbol sym;
	if (name == "stdin") {
	    env->set_input(boost::dynamic_pointer_cast<symbol>(env->get_value_read("stdin")));
	    return;
	}
	FILE *fp = fopen(name.c_str(), "r");
	if (!fp)
	    throw Error(new error(error::fopen));
	sym = Symbol(new symbol(name));
	env->bind(sym, Port(new port(fp)));
	env->set_input(sym);
    }
    void start() {
	Reader read(new reader(env));
	Object obj;
	while (1) {
	    try {
		obj = read->get();
		if (obj == env->get_value("eof"))
		    return;
		obj = obj->eval(env);
		obj->print(env);
	    } catch (Error err) {
		std::cout << "Error: " << err->msg << "." << std::endl;
	    }
	}
    }
};
typedef boost::shared_ptr<tizp> Tizp;
#endif
